package BookStore;

import java.util.Properties;

import org.apache.log4j.Logger;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.InvalidName;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManager;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;

import BookStore.managers_impl.AuctionMgr.AuctionMgr;
import BookStore.managers_impl.CatalogBookStoreMgr.CatalogBookStoreMgr;
import BookStore.managers_impl.DeliveryBookStoreMgr.DeliveryBookStoreMgr;
import BookStore.managers_impl.MinimumMarginMgr.MinimumMarginMgr;
import Util.Util;
import be.fundp.info.util.logging.MyLogger;

/**
 * Book Store main
 * @author Loup
 *
 */
public class BookStoreMain {
	private static String csv;
	private static String ip;
	private static String port;
	private static String id;
	public static final String prop = "BookStore2.properties";
	private static final String log4j = "log4j.properties";
	
	private ORB orb;

	

	public static void main(String args[]) throws NotFound, CannotProceed,
			InvalidName {
		
		csv = Util.getPropertiesAttribute(prop, "csv");
		ip = Util.getPropertiesAttribute(prop, "ip");
		port = Util.getPropertiesAttribute(prop, "port");
		id = Util.getPropertiesAttribute(prop, "id");
		if(!MyLogger.isConfigured())
			MyLogger.initLogger(log4j);
		final Logger logger = MyLogger.getLogger(Class.class);
		
		if(csv ==null || ip == null || port == null || id == null){
			logger.info("[ERROR] file "+prop+" is absent");
			return;
		}
		


		

		// build properties for orb
		Properties props = new Properties();
		props.put("org.omg.CORBA.ORBInitialHost", ip);
		props.put("org.omg.CORBA.ORBInitialPort", port);

		// initialize ORB and rootPOA
		ORB orb = ORB.init(new String[] { "-ORBInitialPort", port,
				"-ORBInitiaHost", ip }, props);
		POA rootPOA = null;

		try {
			rootPOA = POAHelper.narrow(orb
					.resolve_initial_references("RootPOA"));
		} catch (org.omg.CORBA.ORBPackage.InvalidName e) {
			logger.fatal("unable to resolve rootpoa, exiting.\n", e);
			System.exit(1);
		}

		// get naming service reference (using RootPOA)
		NamingContext naming = NamingContextHelper.narrow(orb
				.string_to_object("corbaloc:iiop:" + ip + ":" + port
						+ "/NameService"));



		NameComponent[] name = new NameComponent[] { new NameComponent(
				"Auction", "Object" + id) };
		
		NameComponent[] name2 = new NameComponent[] { new NameComponent(
				"Margin", "Object" + id) };
		
		NameComponent[] name3 = new NameComponent[] { new NameComponent(
				"Catalog", "Object" + id) };
		
		NameComponent[] name4 = new NameComponent[] { new NameComponent(
				"Delivery", "Object" + id) };
		
		// create servants (managers)
		AuctionMgr auction_impl = new AuctionMgr(orb, id);
		MinimumMarginMgr margin_impl = new MinimumMarginMgr() ;
		CatalogBookStoreMgr catalog_impl = new CatalogBookStoreMgr(csv);
		DeliveryBookStoreMgr delivery_impl = new DeliveryBookStoreMgr();
		try {
			rootPOA.activate_object(auction_impl);
			rootPOA.activate_object(margin_impl);
			rootPOA.activate_object(catalog_impl);
			rootPOA.activate_object(delivery_impl);
		} catch (Exception e) {
			logger.error(e);
		}

		// bind object into the naming service
		try {
			naming.bind(name, auction_impl._this_object());
		} catch (Exception e) {
			naming.rebind(name, auction_impl._this_object());
			logger.fatal(e);
		}
		
		try {
			naming.bind(name2, margin_impl._this_object());
		} catch (Exception e) {
			naming.rebind(name2, margin_impl._this_object());
			logger.fatal(e);
		}
		
		try {
			naming.bind(name3, catalog_impl._this_object());
		} catch (Exception e) {
			naming.rebind(name3, catalog_impl._this_object());
			logger.fatal(e);
		}
		try {
			naming.bind(name4, delivery_impl._this_object());
		} catch (Exception e) {
			naming.rebind(name4, delivery_impl._this_object());
			logger.fatal(e);
		}
		
		
		
		logger.debug("published "
				+ orb.object_to_string(auction_impl._this_object()));
		logger.debug("published "
				+ orb.object_to_string(margin_impl._this_object()));
		logger.debug("published "
				+ orb.object_to_string(catalog_impl._this_object()));
		logger.debug("published "
				+ orb.object_to_string(delivery_impl._this_object()));
		logger.info("Bookstore :"+id+" is launched");
		// get manager and activate it
		POAManager manager = rootPOA.the_POAManager();
		try {
			manager.activate();
		} catch (AdapterInactive e) {
			logger.fatal("cannot activate manager.\n", e);
			System.exit(1);
		}
		// block thread until orb is stopped
		logger.info("run orb, hang current thread.");
		orb.run();
	}
	
	
	
	public static String getCSV(){
		return csv;
	}
	


}
